#Starlink をPrometheusで監視しAmazon ECS AnywhereでAWS連携する
ども、大瀧です。
東日本の皆さん、先日サービス開始したStarlinkを活用してますか。アンテナを設置する場所の視界など安定利用のためには独特な要件があり、Starlinkスマートフォンアプリで視界のチェックや直近の切断履歴などを参照できます。一方でアプリで参照できる履歴は直近7時間分であったり、アプリ利用のためにスマートフォンを用意する必要があったりと使い方によっては不便な面もあります。そこで本ブログでは、Starlinkの運用に役立つ監視の仕組みとしてPrometheusとAWSクラウドを組み合わせた構成をご紹介します。
StarlinkキットにはgRPC APIが生えている
Starlinkを契約すると送付される衛星受信キットにはアンテナ本体(以下Dish)とWi-Fiルーター(以下Starlinkルーター)が含まれており、どちらにもgRPCのAPIがありアクセスできます。StarlinkアプリがStarlink回線(Wi-Fi)に接続しているときにこのAPIを利用して情報を参照しているようです。で、有志がこのAPIの非公式情報をGitHubに公開しています。
APIを叩く非公式Prometheus Exporterもあります。
このStarlink Exporterを含めたPrometheus+Granafaコンテナを一発で立ち上げるDocker Compose構成にStarlink Monitoring Systemと名付けたものをExporterの作者が公開しています。
まずは手元にあるRaspberry Piを有線LANでStarlinkルーターに接続し、これを動作させてみました。
- Raspberry Pi: Raspberry Pi 4 モデルB 8GB
- OS: Ubuntu Server 20.04.5 LTS
- Docker: Docker Engine - Community 20.10.21
$ git clone https://github.com/danopstech/starlink.git $ cd starlink $ sudo docker-compose up -d
WebブラウザでRaspberry Piのホスト名やIPアドレスの3000番ポートにアクセスすると、Grafanaのログイン画面が表示されます。
初期ユーザー名 admin
とパスワード admin
でログインできます *1。ログイン後の初期画面に遷移したら左のメニューからSearchでダッシュボードの検索画面を表示、 starlink
で検索すると、Starlink Exporterのメトリクスを表示するStarlinkダッシュボードを表示できます。
Prometheusで保存している(保存期間は15日間)様々なデータのグラフが表示されます。かっこいい!
一方で、画面上部のID周りは軒並み No Data
ということに気づきます。グラフではメトリクス starlink_dish_cell_id
などを参照しているので、cURLで直接Starlink Exporterを動作させ様子を見てみると。。。
pi@raspberrypi:~$ curl localhost:9817/metrics | grep -v '^#' starlink_dish_alert_mast_not_near_vertical 0 starlink_dish_alert_motors_stuck 0 starlink_dish_alert_slow_eth_speeds 0 starlink_dish_alert_thermal_shutdown 0 starlink_dish_alert_thermal_throttle 0 starlink_dish_alert_unexpected_location 0 starlink_dish_backup_beam 0 starlink_dish_bore_sight_azimuth_deg 0 starlink_dish_bore_sight_elevation_deg 0 starlink_dish_cell_id 0 starlink_dish_currently_obstructed 0 starlink_dish_downlink_throughput_bytes 0 starlink_dish_first_nonempty_slot_seconds -1 starlink_dish_fraction_obstruction_ratio 0 starlink_dish_info{country_code="",device_id="",hardware_version="",software_version="",utc_offset="0"} 1 starlink_dish_initial_gateway_id 0 starlink_dish_initial_satellite_id 0 starlink_dish_last_24h_obstructed_seconds 0 starlink_dish_pop_ping_drop_ratio 1 starlink_dish_pop_ping_latency_seconds -0.0010000000474974513 starlink_dish_pop_rack_id 0 starlink_dish_prolonged_obstruction_duration_seconds 0 starlink_dish_prolonged_obstruction_interval_seconds NaN starlink_dish_scrape_duration_seconds 0.013614033 starlink_dish_snr 0 starlink_dish_state 0 starlink_dish_time_to_slot_end_seconds 0 starlink_dish_up 1 starlink_dish_uplink_throughput_bytes 9328.1318359375 starlink_dish_uptime_seconds 0 starlink_dish_valid_seconds 0
えっと、Exporter側では多くのデータを取得できていないようですね?。APIの仕様はStarlinkアプリのバージョンアップなどに連動して改変されているようで、例えば以下のIssueで問題が報告されています。
このIssueからいくつかリンクを徘徊すると、SysdigによってフォークされAPIを更新したものを見つけました。Docker Composeで指定するDockerイメージをそちらに変更すると、取得できる項目がいくつか増えました。
version: "3.3" services: starlink_exporter: image: "sysdigdan/starlink_exporter:latest"
再度試してみると。。。
pi@raspberrypi:~$ curl localhost:9817/metrics | grep -v '^#' starlink_dish_alert_install_pending 0 starlink_dish_alert_is_heating 0 starlink_dish_alert_mast_not_near_vertical 0 starlink_dish_alert_motors_stuck 0 starlink_dish_alert_roaming 0 starlink_dish_alert_slow_eth_speeds 0 starlink_dish_alert_thermal_shutdown 0 starlink_dish_alert_thermal_throttle 0 starlink_dish_alert_unexpected_location 0 starlink_dish_anti_rollback_version 0 starlink_dish_boot_count 10 starlink_dish_bore_sight_azimuth_deg 1.4277397394180298 starlink_dish_bore_sight_elevation_deg 63.974029541015625 starlink_dish_currently_obstructed 0 starlink_dish_dish_stow_requested 0 starlink_dish_downlink_throughput_bytes 18631.09765625 starlink_dish_eth_speed 1000 starlink_dish_first_nonempty_slot_seconds 0 starlink_dish_fraction_obstruction_ratio 0.03731893002986908 starlink_dish_gps_sats 13 starlink_dish_gps_valid 1 starlink_dish_info{country_code="JP",device_id="ut01000000-00000000-XXXXXXXX",hardware_version="rev2_proto4",manufactured_version="",software_version="223c055e-8fe8-42e6-8d00-cd4c6a466252.uterm.release",utc_offset="32401"} 1 starlink_dish_info_debug{count_by_reason="map[]",count_by_reason_delta="map[]",last_count="0",last_reason="BOOT_REASON_UNKNOWN"} 1 starlink_dish_is_dev 0 starlink_dish_is_hit 0 starlink_dish_outage_did_switch 0 starlink_dish_outage_duration{cause="UNKNOWN",start_time="0"} 0 starlink_dish_pop_ping_drop_ratio 0 starlink_dish_pop_ping_latency_seconds 0.02257142774760723 starlink_dish_prolonged_obstruction_duration_seconds 1.5567706823349 starlink_dish_prolonged_obstruction_interval_seconds 224.99998474121094 starlink_dish_prolonged_obstruction_valid 0 starlink_dish_scrape_duration_seconds 0.007364572 starlink_dish_software_partitions_equal 0 starlink_dish_up 1 starlink_dish_uplink_throughput_bytes 17238.58984375 starlink_dish_uptime_seconds 21020 starlink_dish_valid_seconds 20613
ざっと眺めた感じでは、Starlinkアプリの[SETTINGS] - [ADVANCED] - [DEBUG DATA]で表示できるSTARLINK DISHの項目と近いものが並んでいる気がします。
AWSと連携する
ここまではRaspberry PiでDockerを用いてPrometheusとGrafanaを実行しました。データの保存や複数のキットを監視するユースケースを考えると、いずれもクラウド上に構成するのがより良いと考えられます。また、Dockerコンテナの設定変更やコンテナ自体の実行状態の管理などもクラウドに任せたいですね。そこで、それらの機能を提供するAWSマネージドサービスと組み合わせた構成を示します。
それぞれの役割を以下に解説します。Prometheusサーバーの役割がADOT CollectorとAMPに分かれているのがポイントです。
項目名 | 説明 |
---|---|
Prometheus Exporterコンテナ | Starlink DishのgRPC APIにアクセスしメトリクスを取得する |
AWS Distro for OpenTelemetry(ADOT) Collectorコンテナ | Prometheus Exporterへのメトリクスの定期取得とAMPへのメトリクス送信 |
Amazon Managed Service for Prometheus(AMP) | ADOT Collectorコンテナから送信されるメトリクスを受け取り、保存する |
Amazon Managed Service for Grafana(AMG) | AMPにメトリクスをクエリし、ダッシュボードで可視化する |
Amazon ECS Anywhere | Raspberry Piで実行するDockerコンテナの管理や監視、コンテナログ管理 *2 |
具体的な設定手順は、以下の記事とほぼ同等です。
上記ブログ記事では外形監視用途にBlackbox Exporterを用いていたので、それを今回のStarlink Exporterに差し替える形です。差し替える部分をピックアップします。
ADOT Collectorの設定
--- receivers: prometheus: config: global: scrape_interval: 60s scrape_timeout: 10s scrape_configs: - job_name: 'starlink' scrape_interval: 3s scrape_timeout: 3s static_configs: - targets: ['exporter:9817'] exporters: awsprometheusremotewrite: endpoint: "https://aps-workspaces.<リージョン名>.amazonaws.com/workspaces/ws-<ワークスペースID>/api/v1/remote_write" timeout: 60s read_buffer_size: 4096 aws_auth: region: "ap-northeast-1" service: "aps" extensions: health_check: pprof: endpoint: :1888 zpages: endpoint: :55679 service: extensions: [pprof, zpages, health_check] pipelines: metrics: receivers: [prometheus] exporters: [awsprometheusremotewrite]
blackbox_exporterコンテナの定義
項目名 | 値 |
---|---|
コンテナ名 | starlink-exporter |
イメージ | sysdigdan/starlink_exporter:latest |
ポートマッピング - ホストポート | <空欄のまま> |
ポートマッピング - コンテナポート | 9817 |
ポートマッピング - プロトコル | tcp |
ログ設定 | Auto-configure CloudWatch Logsをオン |
aws-otel-collectorコンテナの定義(差替部分のみ抜粋)
項目名 | 値 |
---|---|
ネットワーク設定 - リンク | starlink-exporter:exporter |
この構成にすることで、Starlinkキットを様々な場所に大規模配置するようなケースでも一元的に監視し管理出来るようになりますね。
なお、そのときはADOT Collectorの設定にlabelsで設置場所固有のラベルなどを付け、AMPおよびAMGで識別できるようにすると良いでしょう。
まとめ
StarlinkキットにはgRPC APIがありPrometheusのexporterを用いて監視に利用できることと、ECS AnywhereとADOT Collectorを用いてAWSと連携する様子をご紹介しました。